package cn.le.io;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 管道  Unix系统中,管道被用来连接一个进程的输出和另一个进出的输入,Java nio中的Pipe类实现一个管道的范例,不过它所创建的管道是进程内
 * (Java虚拟机集成内)而非进程间使用的,也就是说,pipe通常用于两个线程之间的通信,
 * pipe定义了两个嵌套的通道类来实现管路,这两个类是pipe.SourceChannel(管道负责读的一端)和pipe.SinkChannel(管道负责写的一端)
 *
 *
 */
public class PipeDemo {

    public static void main(String[] args) throws IOException {

        Pipe pipe = Pipe.open();
        PipeWriter pipeWriter = new PipeWriter(pipe);
        PipeReader pipeReader = new PipeReader(pipe);

        ExecutorService exec = Executors.newFixedThreadPool(2);
        exec.submit(pipeWriter);
        exec.submit(pipeReader);
    }

}

class PipeWriter implements Callable<Boolean> {

    Pipe pipe;

    public PipeWriter(Pipe pipe)
    {
        this.pipe = pipe;
    }

    @Override
    public Boolean call() throws Exception {

        Pipe.SinkChannel sinkChannel = pipe.sink();
        for (int i = 10; i >= 0; i--)
        {
            String msg = "嫦娥6号飞船发射倒计时:"+i;
            ByteBuffer buf = ByteBuffer.wrap(msg.getBytes("utf-8"));
            //往通道写数据
            sinkChannel.write(buf);
            TimeUnit.SECONDS.sleep(1);
        }
        String msg = "嫦娥6号飞船发射成功!";
        ByteBuffer buf = ByteBuffer.wrap(msg.getBytes("utf-8"));
        sinkChannel.write(buf);
        return true;
    }
}

class PipeReader implements Callable<Boolean>{

    Pipe pipe;

    public PipeReader(Pipe pipe)
    {
        this.pipe = pipe;
    }

    @Override
    public Boolean call() throws Exception {

        Pipe.SourceChannel sourceChannel = pipe.source();
        ByteBuffer buf = ByteBuffer.allocate(128);
        //循环读取通道数据
        while (sourceChannel.read(buf) != -1)
        {
            buf.flip();
            System.out.println(Charset.forName("utf-8").decode(buf));
            buf.clear();
        }
        return true;
    }
}







